#  Copyright (c) 2023. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
#  Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
#  Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
#  Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
#  Vestibulum commodo. Ut rhoncus gravida arcu.
# coding:utf8


from log import logger
import os
from project import IP
import re
from functools import partial
from typing import Callable
from project.SipMachine.var import Path, DEFAULT_PBX_TAIL, debug

DEBUG = debug


class Handle:
    re_ip = ""
    re_pbx = ""
    re_gateway = ""
    re_name = ""
    re_name1 = ""
    re_name2 = ""
    re_password = ""
    
    def __init__(self, file_path="", ip=None, pbx=None, tail=None, section=None):
        
        self.ip = ip
        self.ip_gateway = ""
        self.pbx = pbx
        self.password = ""
        
        
        
        if os.path.exists(file_path):
            self.file_path = file_path
            self.rereadfile()
        else:
            if not DEBUG:
                raise ValueError("|{}| 路径不存在".format(file_path))
            
        
        logger.debug("{} object is create".format(self.__class__.__name__))
        # logger.debug("pbx-ip: {}".format(self.pbx))
        # logger.debug("ip: {}".format(self.ip))
    
    def rereadfile(self):
        with open(self.file_path, 'r', encoding='utf8') as f:
            filetext = f.read()
            # logger.debug(filetext)
            rev= self.sets_from_filetext(filetext)
            if not rev:
                raise TypeError("文件读取错误, 路径: {}".format(self.file_path))
    
    def set_password(self, password: str):
        self.password = password
        
    def sets_from_filetext(self, file_txt):
        return all([
        self.get_ip_from_filetext(file_txt),
        self.get_pbx_from_filetext(file_txt),
        self.get_gateway_from_filetext(file_txt),
        self.get_password_from_filetext(file_txt),
            ])
        
     
    def sets(self, file_path=None, ip=None, pbx=None, tail=None, section=None):
        """
        从外部设置ip, pbx, gateway
        """
        # 默认的ip和pbx的前缀
        _prefix = "192.168"
        
        # set ip
        if ip is not None:
            # prior ip
            self.ip = ip
        elif tail is not None and section is not None:
            arg = _prefix, section, tail
            ipo = IP.generate_ip_obj(arg)
            self.ip = ipo.ip
        else:
            raise ValueError("ip, tail, section error, all it not value")
    
        # set pbx
        # prior pbx, else, default tail 240
        if pbx is not None:
            self.pbx = pbx
    
        else:
            # 240
            # DEFAULT_PBX_TAIL
            arg = _prefix, section, str(DEFAULT_PBX_TAIL)
            ipo = IP.generate_ip_obj(arg)
            self.pbx = ipo.ip
        
        
        self._set_default_gateway()
        
        
    def ip_add_1(self, n=1):
        ipo = IP(self.ip)
        self.ip = ipo.next_ip(n)
    
    def ip_subtraction_1(self, n=1):
        ipo = IP(self.ip)
        self.ip = ipo.last_ip(n)
        
    def set_pbx(self, ipstr):
        try:
            _ = IP(ipstr)
            self.pbx = ipstr
            return True
        except TypeError:
            return  False
    
    @staticmethod
    def _repl_func(ip_str, match):
        return match.group(1) + ip_str + match.group(3)

    def change_ip_to_filetext(self, file_text: str):
        repl_func: Callable = partial(self._repl_func, self.ip)
        file_text_ = re.sub(self.re_ip, repl_func, file_text)
        return file_text_
        
    def change_pbx_to_filetext(self, file_text: str):
        """
        设置pbx的IP
        file_text: 配置文件的内容
        pbx的ip为 init中的pbx
        """
        repl_func: Callable = partial(self._repl_func, self.pbx)
        file_text_ = re.sub(self.re_pbx, repl_func, file_text)
        return file_text_
        pass
    
    def change_gateway_to_filetext(self, file_text: str):
        """
        设置网关的ip
        file_text: 配置文件的内容
        pbx的ip为 init中的网关
        """
        repl_func: Callable = partial(self._repl_func, self.ip_gateway)
        file_text_ = re.sub(self.re_gateway, repl_func, file_text)
        return file_text_
    
    def change_name_to_filetext(self, file_text: str):
        """
        设置配置文件中的 三个8开头的name e.g 8002
        file_text: 配置文件的内容
        
        3 name 是从self.ip中求得的, 不需要单独设置
        """
        
        repl_func: Callable = partial(self._repl_func, self._get_num())
        file_text = re.sub(self.re_name, repl_func, file_text)
        file_text = re.sub(self.re_name1, repl_func, file_text)
        file_text = re.sub(self.re_name2, repl_func, file_text)
        return file_text
    
    def change_password_to_filetext(self, file_text: str):
        """
        设置配置文件中的密码  默认为XD123456
        file_text: 配置文件的内容
        """
        
        logger.debug("re: {}, password: {}".format(self.re_password, self.password))
        repl_func: Callable = partial(self._repl_func, self.password)
        file_text = re.sub(self.re_password, repl_func, file_text)
        return file_text

    
    def get_ip_from_filetext(self, file_text: str):
        """
        
        """
        match = re.search(self.re_ip, file_text)
        if match:
            self.ip = match.group(2)
            logger.debug("get ip : {}".format(self.ip))
            return True

    def get_pbx_from_filetext(self, file_text: str):
        match = re.search(self.re_pbx, file_text)
        if match:
            self.pbx = match.group(2)
            logger.debug("get pbx : {}".format(self.pbx))
            return True

    def get_gateway_from_filetext(self, file_text: str):
        match = re.search(self.re_gateway, file_text)
        if match:
            self.ip_gateway = match.group(2)
            logger.debug("get gateway : {}".format(self.ip_gateway))
            return True

    def get_password_from_filetext(self, file_text: str):
        match = re.search(self.re_password, file_text)
        if match:
            self.password = match.group(2)
            return True


    def get_tail(self):
        ipo = IP(self.ip)
        return ipo.tail()

    
    def get_section(self):
        ipo = IP(self.ip)
        return ipo.section()
    
    def _get_num(self):
        tail = self.get_tail()
        tail_ = int(tail)
        return "8{:0>3}".format(tail_)
    
    def _set_default_gateway(self):
        ipo = IP(self.ip)
        self.ip_gateway = ipo.replace_tail('1')
        
     
    
    def handle_file(self):
        with open(self.file_path, 'r', encoding='utf8') as f:
            file_text = f.read()
            
        with open(self.file_path, 'w', encoding='utf8') as f:
            file_text = self.change_ip_to_filetext(file_text)
            file_text = self.change_pbx_to_filetext(file_text)
            file_text = self.change_gateway_to_filetext(file_text)
            file_text = self.change_name_to_filetext(file_text)
            file_text = self.change_password_to_filetext(file_text)
            
            # print(file_text)
            f.write(file_text)
            logger.debug("write file")
    
    def __str__(self):
        return f"{self.__class__.__name__} ip: {self.ip}, " \
            f"gateway: {self.ip_gateway}, pbx: {self.pbx}, password: {self.password}"



class HandleOldSipFile(Handle):
    """
    account.1.label = 8010
    account.1.display_name = 8010
    account.1.user_name = 8010
    account.1.password = 123456
    account.1.sip_server.1.address = 192.168.3.241
    network.internet_port.ip = 192.168.3.010
    network.internet_port.mask = 255.255.255.0
    network.internet_port.gateway = 192.168.3.1
    """
    
    re_ip = r"(network.internet_port.ip\s*=\s*)(.+)(\n)"
    re_pbx = r"(account.1.sip_server.1.address\s*=\s*)(.+)(\n)"
    re_gateway = r"(network.internet_port.gateway\s*=\s*)(.+)(\n)"
    re_name = r"(account.1.label\s*=\s*)(\d+)(\n)"
    re_name1 = r"(account.1.display_name\s*=\s*)(\d+)(\n)"
    re_name2 = r"(account.1.user_name\s*=\s*)(\d+)(\n)"
    re_password = r"(account.1.password\s*=\s*)(\w+)(\n)"



class HandleNewSipFile(Handle):
    re_ip = r"(WAN IP\s*:)(.+)(\n)"
    re_gateway = r"(WAN Gateway\s*:)(.+)(\n)"
    re_pbx = r"(SIP1 Register Addr\s*:)(.+)(\n)"
    re_name = r"(SIP1 Phone Number\s*:)(\d+)(\n)"
    re_name1 = r"(SIP1 Display Name\s*:)(\d+)(\n)"
    re_name2 = r"(SIP1 Register User\s*:)(\d+)(\n)"
    re_password = r"(SIP1 Register Pswd\s*:)(.+)(\n)"
                     # SIP1 Register Pswd


class HandleSipFileAuto:
    def __init__(self, path):
        
        try:
            self.handfile = HandleNewSipFile(path)
            self.filetype = 'new'
            return
        except TypeError:
            pass
        
        try:
            self.handfile = HandleOldSipFile(path)
            self.filetype = 'old'
            return
        except TypeError:
            pass
        raise TypeError("文件错误, 无法匹配new and old ")
            


if __name__ == '__main__':
    # print(HandleNewSipFile.re_ip)
    # print(re.search(HandleNewSipFile.re_ip, file_txt).group(1))
    # print(re.search(HandleNewSipFile.re_ip, file_txt, re.I))
    # print(re.search(HandleNewSipFile.re_ip, file_txt, re.S))
    # print(re.search(HandleNewSipFile.re_ip, file_txt, re.U))
    # print(re.search(HandleNewSipFile.re_ip, file_txt, re.A))
    # print(re.search(HandleNewSipFile.re_ip, file_txt, re.M))
    # print(re.search(HandleNewSipFile.re_ip, file_txt, re.L))
    # print(re.search(HandleNewSipFile.re_ip, file_txt, re.X))
    
    # obj = HandleNewSipFile()
    # obj.sets_from_filetext(file_txt)
    # print(obj)
    # obj.ip = "192.168.12.128"
    # obj._set_default_gateway()
    # obj.pbx = "192.168.12.241"
    # obj.set_password("XD123456")
    #
    # print(obj.re_password)
    # file_txt = obj.change_ip_to_filetext(file_txt)
    # file_txt = obj.change_gateway_to_filetext(file_txt)
    # file_txt = obj.change_pbx_to_filetext(file_txt)
    # file_txt = obj.change_name_to_filetext(file_txt)
    # file_txt = obj.change_password_to_filetext(file_txt)
    # print(file_txt)
    #

    from project.SipMachine.var import Path
    path = Path.get_path(Path.configSipTestDict)
    obj = HandleNewSipFile(path)
    obj.ip_add_1()
    obj.set_password("XD123456")
    obj.handle_file()
    print(obj._get_num())
    
    # print(obj)
    
    # obj = HandleOldSipFile(Path.oldsip)
    # obj.ip_add_1()
    # obj.set_password("XD123456")
    # obj.handle_file()
    # print(obj)
    
    # obj = HandleSipFileAuto(Path.oldsip)
    # handle = obj.handfile
    # handle.ip_add_1()
    # handle.set_password("XD123456")
    # handle.handle_file()
    # print(handle)
